/***
 * 富文本的插入代码，代码修饰功能
 * @Author: kevin.huang 
 * ****/
function initCodeEditor(window, document) {
    if (window["_codeCssObject_"]) {
        window["_codeCssObject_"].setTartets(window, document);
        return;
    }
    var code = new CodeCss(window, document);
    window["_codeCssObject_"] = code;
}

/***
 * 代码修饰类封装
 * ****/
function CodeCss(window, document) {
    $B.extend(this, CodeCss); //继承父类 
    this.range = undefined;
    this.setTartets(window, document);
}
CodeCss.prototype = {
    setTartets: function (window, document) {
        this.window = window;
        this.document = document;
        var body = $(document.body);   
        this.$inputWrap = body.find("#input_txt");            
        this.$input = this.$inputWrap.children("#k_code_input");
        this.$tool = body.find("#toolbar");
        this.head = $(document).find("head");
        this.bindEvnets();
        this.clearBg = true;
    },
    removeTargets: function () {
        try {
            this.$inputWrap.remove();
            this.$tool.remove();
            this.$inputWrap = undefined;
            this.$tool = undefined;
        } catch (ex) {
        }
    },
    /***
     * 清理背景色
     * ***/
    clearBackground: function (el) {
        el.css("background", "none");
        var color = el.css("color");
        if($B.isContrastYIQ(color) === "light"){//变深色
            var dcolor = $B.lightenDarkenColor(color.toHexColor() ,-45); //调用核心方法处理浅色
            el.css("color", dcolor);
        }
        var _this = this;
        el.children().each(function () {
            _this.clearBackground($(this));
        });
    },
    /***
     * 替换i标签
     * ***/
    replaceIelement: function (html) {
        html = html.replace(/(<\/i>)/gi, "</span>");
        html = html.replace(/(<\/em>)/gi, "</span>");
        return html;
    },
    /***
     * 绑定事件
     * **/
    bindEvnets: function () {
        var _this = this;
        this.$tool.children(".font_css").focus(function () {
            _this.rebuildUserRange();
        }).click(function () {
            var $t = $(this);
            var id = $t.attr("id");
            var css;
            var sColor;
            if (id === "bold") {
                css = { "font-weight": "bold" };
            } else if (id === "normal") {
                css = { "font-weight": "normal" };
            } else {
                sColor = $t.attr("color");
                css = { "color": sColor };
            }
            if (sColor) {
                _this.changeSelectionColor("color", sColor);
            }
            _this.document.designMode = "on";
            var res = _this.document.execCommand("italic", "false", null);
            _this.document.designMode = "off";
            var eles = _this.getCssElementArray();
            eles.each(function () {
                var el = $(this);
                _this.loopCss(el, css);
            });
        });
        this.$tool.children("#fontSize").children("select").focus(function () {
            _this.rebuildUserRange();
        }).on("change", function () {
            var v = $(this).val() + "px";
            _this.document.designMode = "on";
            _this.document.execCommand("italic", "false", null);
            _this.document.designMode = "off";
            var css = { "font-size": v };
            var eles = _this.getCssElementArray();
            eles.each(function () {
                var el = $(this);
                _this.loopCss(el, css);
            });
        });
        this.$tool.children("#isClearBackground").children("select").on("change", function () {
            var v = $(this).val();
            if (v === "1") {
                _this.clearBg = false;
            } else {
                _this.clearBg = true;
            }
        });
        this.$inputWrap.mouseleave(function () {
            _this.setDomRange();
        }).mousedown(function () {
            _this.head.children("#_selection_style").remove();
        }).on("paste", function (e) {           
            setTimeout(function () {
                console.log("粘贴 》》》》》");
                if (_this.clearBg) {
                    _this.setDomRange();
                    var r = _this.range;
                    var ancestor = r.commonAncestorContainer;
                    if (ancestor.nodeType === 3) {
                        ancestor = $(ancestor.parentNode);
                    } else {
                        ancestor = $(ancestor);
                    }
                    var wrap = _this.$input;
                    while (ancestor[0].tagName !== "PRE") {
                        wrap = ancestor;
                        ancestor = ancestor.parent();
                    }
                    //console.log("paste >>>>>>");
                    _this.clearBackground(wrap);
                }            
            }, 0);
        });
        this.$tool.children("#_clr_btn_").click(function () {
            _this.$input.html("");
        });
    },
    /***
     * 获取Dom Selection
     * **/
    getDomSelection: function () {
        var selection;
        if (this.window.getSelection) {
            selection = this.window.getSelection();
        } else if (this.document.selection) {
            selection = this.document.selection.createRange();
        }
        return selection;
    },
    /***
     * 保持Dom range
     * ***/
    setDomRange: function () {
        var seletionObj = this.getDomSelection();
        if (seletionObj.getRangeAt && seletionObj.rangeCount > 0) {
            this.range = seletionObj.getRangeAt(0);
        } else { // 老版本浏览器
            if (seletionObj.anchorNode) {
                this.range = this.document.createRange();
                this.range.setStart(seletionObj.anchorNode, seletionObj.anchorOffset);
                this.range.setEnd(seletionObj.focusNode, seletionObj.focusOffset);
            }
        }
        if (!this.range) {
            console.log("code css getDomRange 异常........^^.^^");
        }
    },
    /***
     * 根据this.range 重建 选区
     * * */
    rebuildUserRange: function () {
        if (this.range) {
            var selection = this.getDomSelection();
            try {
                selection.removeAllRanges();
            } catch (e) {
            }
            selection.addRange(this.range);
        }
    },
    /**递归修饰**/
    loopCss: function (el, css) {
        el.css(css).removeAttr("size").removeAttr("color");
        var _this = this;
        el.children().each(function () {
            _this.loopCss($(this), css);
        });
    },
    /***
     * 创建选区
     * **/
    createRange: function (firstChild, lastChild, startOffset, endOffset) {
        try {
            this.range = this.document.createRange();
            this.range.setStart(firstChild, startOffset);
            this.range.setEnd(lastChild, endOffset);
            var sel = this.window.getSelection();
            try {
                sel.removeAllRanges();
            } catch (ex) { }
            sel.addRange(this.range);
        } catch (ex) {
            console.log("error");
        }
    },
    changeSelectionColor: function (cssName, cssValue) {
        var style = '#input_txt *::selection{' + cssName + ':' + cssValue + ';background-color:#338FFF;}' +
            '#input_txt *::-moz-selection{' + cssName + ':' + cssValue + ';background-color:#338FFF;}' +
            '#input_txt *::-webkit-selection{' + cssName + ':' + cssValue + ';background-color:#338FFF;}';
        this.head.children("#_selection_style").remove();
        this.head.append("<style id='_selection_style'>" + style + "</style>");
    },
    /***
     * 获取修饰目标
     * **/
    getCssElementArray: function () {
        var barray = this.$inputWrap.find("i");
        if (barray.length === 0) {
            barray = this.$inputWrap.find("em");
        }
        barray.each(function () {
            var $t = $(this);
            var pEl = $t.parent();
            var style = "";
            if (pEl[0].tagName !== "PRE") {
                style = pEl.attr("style");
            }
            var txt = $t.text();
            var prevSibling = $t[0].previousElementSibling;
            var nextSibling = $t[0].nextElementSibling;
            if (!prevSibling && !nextSibling && pEl.children().length === pEl.contents().length) {
                pEl.text(txt).addClass("_target");
            } else {
                $t.replaceWith("<span style='" + style + "' class='_target'>" + txt + "</span>");
            }
        });
        barray = this.$inputWrap.find("._target");
        var startNode = barray.first()[0];
        var endNode = barray.last()[0];
        var endLen;
        if (endNode.childNodes) {
            endLen = endNode.childNodes.length;
        } else {
            endLen = endNode.length;
        }
        this.createRange(startNode, endNode, 0, endLen);
        setTimeout(function () {
            barray.each(function () {
                $(this).removeClass("_target");
            });
        }, 1);
        return barray;
    }
};